package org.softee.functional.samples;

import static org.softee.functional.Functionals.forEach;
import static org.softee.functional.operation.Functions.stringLength;
import static org.softee.functional.operation.Predicates.isUppercase;
import static org.softee.functional.operation.ReduceFunctions.maxInteger;

import java.util.ArrayList;
import java.util.Collection;

import org.softee.functional.operation.Function;
import org.softee.functional.operation.Predicate;
import org.softee.functional.operation.ReduceFunction;

public class Wiki {

    public void sampleMapReduceCustom() {
        Collection<String> strings = new ArrayList<String>();
        // ...

        Function <String, Integer> stringLength = new Function<String, Integer>() {
            @Override
            public Integer apply(String input) {
                return (input == null) ? 0 : input.length();
            }
        };

        Predicate<String> isUppercase = new Predicate<String>() {
            @Override
            public boolean apply(String input) {
                return (input != null) && input.toUpperCase().equals(input);
            }
        };

        ReduceFunction<Integer> max = new ReduceFunction<Integer>() {
            @Override
            public Integer apply(Collection<Integer> input) {
                // Perform a sequential search for max.
                // Leave it to the Functional framework to divide into subtasks when appropriate
                Integer result = null;
                for (int i : input) {
                    if (i > result) {
                        result = i;
                    }
                }
                return result;
            }
        };

        // run filter/map/reduce operation in serial, using the current thread
        int maxLengthUpperCase = forEach(strings)
                .filter(isUppercase)
                .map(stringLength)
                .reduce(max);

        // run filter/map/reduce operation in parallel exploiting all processor cores
        int parallelMaxLengthUpperCase = forEach(strings)
                .parallel()
                .filter(isUppercase)
                .map(stringLength)
                .reduce(max);
    }

    public void sampleMapReduceBuiltin() {
        Collection<String> strings = new ArrayList<String>();
        // ...

        // run filter/map/reduce operation in serial, executing in the current thread
        int maxLengthUpperCase = forEach(strings)
                .filter(isUppercase())
                .map(stringLength())
                .reduce(maxInteger());

        // run filter/map/reduce operation in parallel exploiting all processor cores
        int parallelMaxLengthUpperCase = forEach(strings)
                .parallel()
                .filter(isUppercase())
                .map(stringLength())
                .reduce(maxInteger());
    }
}
